<?php
/**
 * 
 * +------------------------------------------------------------+
 * @category View 
 * +------------------------------------------------------------+
 * 模板引擎基类
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @copyright http://www.judianyun.com 2013
 * @version 1.0
 *
 * Modified at : 2013-2-16 16:43:08
 *
 */
abstract class View extends Base {
	
	///模板默认配置信息
	protected $_config	=	array(
		'compile'	=>	'/compile/',	//模板编译文件存放路径
		'static'	=>	'/cache/',		//静态缓存文件存储路径
		'caching'	=>	false,			//生成静态缓存标识
		'addmodule' => true,            //生成的静态文件路径是否加上模块名
		'lifetime'	=> 120,				//生成静态缓存时间，单位秒
		'suffix'	=>	'.html',		//默认模板文件后缀名
		'template'	=>	'/template/',	//模板存储路径
		'theme'		=>	''				//应用的模板主题
	);
	
	///当前调用的模板文件名
	protected $_template;
	
	///存储模板变量
	protected $_vars = array();
	
	public function __construct($config = null){
		parent::__construct();
		if (!empty($config)) {
			$this->setConfig($config);
		}
	}
	
	public function __get($name){
		if (@property_exists($this,$this->$name)){
			return $this->$name;
		}elseif(isset($this->_config[$name])){
			return $this->_config[$name];
		}
	}
	
	public function get_cache(){
		
	}
	
	//模板赋值
	abstract public function assign($name, $value = '');
	
	//对字符串的模板进行进行并返回解析后的模板内容
	abstract public function compile($string);
	
	//解析模板
	abstract public function fetch($filename='', $cache_id = 0, $suffix = '');
	
	//解析并显示模板
	public function display($filename='', $cache_id = 0, $suffix = ''){
		echo $this->fetch($filename, $cache_id, $suffix);
	}
	
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name setConfig
	 * +------------------------------------------------------------+
	 * 设置模板相关配置信息，可支持同时配置多个
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param  $key
	 * @param  $value
	 *
	 */
	function setConfig($key=null,$value=null){
		if (empty($key)) return ;
		if (is_array($key)){
			foreach ($key as $k=>$v){
				$this->setConfig($k,$v);
			}
		}elseif (isset($this->_config[$key])){
			$this->_config[$key] = $value;
		}
	}
	
	protected function _createStaticPath($cache_id){
	    if (is_numeric($cache_id)){
	       return strtolower(chr(($cache_id - 1)%26 + 65)) . '/' . ($cache_id - 1)%10 . '/' . $cache_id . $this->suffix;
	    }else{
	        return $cache_id . $this->suffix;
	    }
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name _parseTpl
	 * +------------------------------------------------------------+
	 * 模板寻址
	 * 寻址顺序：模板根目录/ -> 模板根目录/模块名/ -> 模块LIB目录/模块名/template/ -> 模板根目录/分组/模块名/
	 * +------------------------------------------------------------+
	 *
	 * @param string $tpl
	 *
	 */
	protected function _parseTpl($tpl='', $cache_id = 0, $suffix = ''){
		if (is_file($tpl)){
			$info = pathinfo($tpl);
			$static = $this->static . ($cache_id !== 0 ? ($this->addmodule ? MODULE_NAME . '/' : '') . $this->_createStaticPath($cache_id) : $info['filename'] . $suffix . '.' . $info['extension']);
			return array(
				'template' => $tpl,
				'compile'  => $this->compile . $info['basename'],
			    'static'   => $static
			);
		}
		
		static $path = null;
		if ($path === null || !inArray($this->template, $path)){
			$theme = $this->theme ? $this->theme . DS : '';
			$path = array();
			if (defined('ACTION_PATH')){
				//对应控制器存放目录下的template目录
				//$theme && $path[] = ACTION_PATH . 'template' . DS . $theme;
				$path[] = ACTION_PATH . 'template' . DS;
				$prefix = substr(ACTION_PATH, strlen(LIB_PATH), -1);
				if ($prefix != ''){
				    $theme && $path[] = $this->template . $theme . $prefix;
					$path[] = $this->template . $prefix . DS;
					if (!preg_match('/[\\/]+/', $prefix) && $prefix != MODULE_NAME){
						$path[] = $this->template . $prefix . DS . MODULE_NAME . DS;
					}
					$prefix = strtolower(substr($prefix, -strlen(MODULE_NAME))) == strtolower(MODULE_NAME) ? substr($prefix, 0, -strlen(MODULE_NAME)) : '';
					if ($prefix != ''){
					    $theme && $path[] = $this->template .$theme . $prefix;
						$path[] = $this->template . $prefix;
					}
				}
				unset($prefix);
			}
			
			if (defined('SUB_LIB_PATH') && SUB_LIB_PATH != ''){
				$subpath = is_dir(SUB_LIB_PATH) ? SUB_LIB_PATH : $this->template . SUB_LIB_PATH;
				if ($theme){
					$path[] = $subpath . $theme . MODULE_NAME . DS;
					$path[] = $subpath . $theme;
				}
				$path[] = $subpath . MODULE_NAME . DS;
				$path[] = $subpath;
				unset($subpath);
			}
			if ($theme){
				$path[] = $this->template . $theme . MODULE_NAME . DS;
				$path[] = $this->template . $theme;
			}
			$path[] = $this->template . MODULE_NAME . DS;
			$path[] = $this->template;
		}
		
		if ($tpl == ''){
			$tpl = ACTION_NAME . $this->suffix;
		}else{
			false===strpos($tpl, '.') && $tpl .= $this->suffix;
			strpos($tpl,':') && $tpl = str_replace(':', DS, $tpl);
		}
		$tplFile = '';
		$path = array_unique($path);
		foreach ($path as $dir){
			$dir = format_dir($dir . DS);
			if (is_dir($dir) && is_file($dir . $tpl)){
				$tplFile = $dir . $tpl;
				break;
			}
		}
		
		if (!is_file($tplFile)){
			E::halt(Helper::L('CLS_V_TPLEXISTS').'：'.$tpl, EXCEPTION_T_SYS);
		}
		
		$tpl = defined('SUB_LIB_PATH') && is_dir(SUB_LIB_PATH) ? md5(SUB_LIB_PATH) . $tpl : substr($tplFile, strlen($this->template));
		$static = $this->static . ($cache_id !== 0 ? ($this->addmodule ? MODULE_NAME . '/' : '') . $this->_createStaticPath($cache_id) : $tpl);
		return array(
			'template' => $tplFile,
			'compile'  => $this->compile . $tpl,
		    'static'   => $static
		);
	}
	
}